package net.xfok.games.xgame;

import java.util.ArrayList;


import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;

public class XGameView extends TileView {
	
	private static final String TAG="XGameView";
	 
	private int mMode = READY;
	public static final int PAUSE = 0;
	public static final int READY = 1;
	public static final int RUNNING = 2;
	public static final int LOSE = 3;
	 
	private int mDirection = 0;
    private int mNextDirection = 0;
    
    private static final int EAST = 3;
    private static final int WEST = 4;
    
    private static final int RED_STAR = 1;
	private static final int YELLOW_STAR = 2;
	private static final int GREEN_STAR = 3;
	
	private TextView mStatusText;
	
	private long mScore = 0;
    private long mMoveDelay = 600;
	
	private ArrayList<Coordinate> mRacket = new ArrayList<Coordinate>();
	
	public void setTextView(TextView newView) {
        mStatusText = newView;
    }
    
	public XGameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		loadTiles();
	}
	
	public XGameView(Context context, AttributeSet attrs,int style) {
		super(context, attrs,style);
		// TODO Auto-generated constructor stub
		loadTiles();
	}
	private RefreshHandler mRedrawHandler = new RefreshHandler();
	class RefreshHandler extends Handler{
		@Override
        public void handleMessage(Message msg) {
            update();
            XGameView.this.invalidate();
        }

        public void sleep(long delayMillis) {
        	this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
        }
	}
	
	private void update(){
		Log.i(TAG, "mMode="+mMode);
        if (mMode == RUNNING) {
        	clearTiles();
            updateWalls();
    		updateRacket();
    		mRedrawHandler.sleep(mMoveDelay);
        }
		
	}
	
	private void loadTiles(){
		setFocusable(true);		
		resetTiles(4);
		Resources r = this.getContext().getResources();
		loadTile(RED_STAR, r.getDrawable(R.drawable.redstar));
        loadTile(YELLOW_STAR, r.getDrawable(R.drawable.yellowstar));
        loadTile(GREEN_STAR, r.getDrawable(R.drawable.greenstar));
	}
	
	public void clearTiles() {
        for (int x = 0; x < mXTileCount; x++) {
            for (int y = 0; y < mYTileCount; y++) {
                setTile(0, x, y);
            }
        }
    }
	/**
     * Draws some walls.
     * 
     */
    private void updateWalls() {
        for (int x = 0; x < mXTileCount; x++) {
            setTile(GREEN_STAR, x, 0);
            setTile(GREEN_STAR, x, mYTileCount - 1);
        }
        for (int y = 1; y < mYTileCount - 1; y++) {
            setTile(GREEN_STAR, 0, y);
            setTile(GREEN_STAR, mXTileCount - 1, y);
        }
    }
    
    private void initNewGame(){
    	mRacket.clear();
    	mRacket.add(new Coordinate(mXTileCount/2-1, mYTileCount-2));
    	mRacket.add(new Coordinate(mXTileCount/2, mYTileCount-2));
    	mRacket.add(new Coordinate(mXTileCount/2+1, mYTileCount-2));
    	mRacket.add(new Coordinate(mXTileCount/2+2, mYTileCount-2));
    	mMoveDelay = 600;
        mScore = 0;
    }
    
    private void updateRacket(){
    	mDirection = mNextDirection;
    	if(mDirection==EAST||mDirection==WEST){
    		Coordinate head = mRacket.get(0);
	    	if(head.x==1||head.x==mXTileCount-2){
	    		setMode(LOSE);
	    		return;
	    	}
	        Coordinate newHead = new Coordinate(1, 1); 	
	    	Log.i(TAG, "mDirection="+mDirection);
	        switch (mDirection) {
		        case EAST: {	        	
		            newHead = new Coordinate(head.x + 1, head.y);
		            break;
		        }
		        case WEST: {
		            newHead = new Coordinate(head.x - 1, head.y);
		            break;
		        }
	        }
	        mRacket.add(0,newHead);
	        mRacket.remove(mRacket.size() - 1);       
    	}
    	for (Coordinate c : mRacket) {
             setTile(RED_STAR, c.x, c.y);
        }
    }
    
    public void setMode(int newMode) {
        int oldMode = mMode;
        mMode = newMode;

        if (newMode == RUNNING & oldMode != RUNNING) {
            mStatusText.setVisibility(View.INVISIBLE);
            update();
            return;
        }
        Resources res = getContext().getResources();
        CharSequence str = res.getString(R.string.hello);
        mStatusText.setText(str);
        mStatusText.setVisibility(View.VISIBLE);
    }
    
    public boolean onKeyDown(int keyCode, KeyEvent msg) {
    	if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
    		if (mMode == READY | mMode == LOSE) {
                /*
                 * At the beginning of the game, or the end of a previous one,
                 * we should start a new game.
                 */
                initNewGame();
                setMode(RUNNING);
                update();
                return (true);
            }
    		if (mMode == PAUSE) {
                setMode(RUNNING);
                update();
                return (true);
            }
    	}
    	if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
    		if(mMode==RUNNING){
    			setMode(PAUSE);
    		}
    		return true;
    	}
    	
    	 if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
             mNextDirection = WEST;
             return (true);
         }

         if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
             mNextDirection = EAST;
             return (true);
         }
         
    	return super.onKeyDown(keyCode, msg);
    }
	
	private class Coordinate {
        public int x;
        public int y;

        public Coordinate(int newX, int newY) {
            x = newX;
            y = newY;
        }

        public boolean equals(Coordinate other) {
            if (x == other.x && y == other.y) {
                return true;
            }
            return false;
        }

        @Override
        public String toString() {
            return "Coordinate: [" + x + "," + y + "]";
        }
    }

}
